using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;

namespace SharedObjects
{
	[DataContract] 
	[ReferencedBy(typeof(Agent))]
	public class Gateway : EntityBase
	{
		[DataMember]
		[Required]
		public ComputerSystem ComputerSystem { get; set; } //1
		
		[DataMember] 
		[Required]
		public List<Cpu> InstalledCpus { get; set; } //1
		
		[DataMember] 
		[Required]
		public GatewayBlueprint GatewayBlueprint { get; set; } //1

		[DataMember] 
		public List<MemoryType> InstalledMemory { get; set; }

		[DataMember]
		public List<NetworkAdapter> InstalledNics { get; set; }

		public double GetTotalCpuSpeed()
		{
			if (InstalledCpus == null)
				return 0;

			return InstalledCpus.Sum(it => it.Modifier);
		}

		public int GetTotalMemory()
		{
			if (InstalledMemory == null)
				return 0;
			return (int)InstalledMemory.Sum(mem => mem.Modifier);
		}

		public double GetTotalBandwidth()
		{
			if (InstalledNics == null)
				return 0;
			return InstalledNics.Sum(it => it.Modifier);
		}

// ReSharper disable UnusedMember.Local
		private double Diminish(int baseValue, double decrease, int stackSize)
// ReSharper restore UnusedMember.Local
		{
			double retval = 0;
			for (int i = 0; i < stackSize; i++)
				retval += Math.Pow(decrease, i) * baseValue;
			return retval;
		}

		public static implicit operator ShallowGateway (Gateway gw)
		{
			ShallowGateway sgw = new ShallowGateway();
			sgw.Id = gw.Id;
			sgw.ComputerSystemId = gw.ComputerSystem.Id;
			sgw.BlueprintId = gw.GatewayBlueprint.Id;
			sgw.CpuIds = new List<ulong>();
			foreach(Cpu cpu in gw.InstalledCpus)
				sgw.CpuIds.Add(cpu.Id);
			sgw.MemoryIds = new List<ulong>();
			foreach(MemoryType mem in gw.InstalledMemory)
				sgw.MemoryIds.Add(mem.Id);

			sgw.NicIds = new List<ulong>();
			foreach(NetworkAdapter nwa in gw.InstalledNics)
				sgw.NicIds.Add(nwa.Id);
			
			return sgw;
		}
	}

	public class ShallowGateway : EntityBase
	{
		public ulong ComputerSystemId { get; set; }
		public List<ulong> CpuIds { get; set; }
		public ulong BlueprintId { get; set; }
		public List<ulong> MemoryIds { get; set; }
		public List<ulong> NicIds { get; set; }
	}
}